package com.zmj.solr.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.zmj.solr.service.IsolrService;
import com.zmj.solr.util.PropertiesUtils;
import com.zmj.solr.vo.SolrProduct;
import com.zmj.solr.vo.SuggestConf;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SpellCheckResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.*;
import org.springframework.data.solr.core.query.result.HighlightEntry;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class IsolrServiceImpl implements IsolrService {

    @Autowired
    private SolrTemplate solrTemplate;

    @Autowired
    private HttpSolrClient client;

    public Map<String, Object> query(Map searchMap) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        //1.先获取从页面传递过来的参数的值   通过KEY获取
        String keywords = (String) searchMap.get("keyword");//获取主查询的条件

        //2.设置主查询的条件
        HighlightQuery query = new SimpleHighlightQuery();
        Criteria criteria = new Criteria("search");
        criteria.contains(keywords);
        query.addCriteria(criteria);
        //3.设置高亮查询的条件   设置高亮显示的域  设置前缀  设置后缀
        HighlightOptions hightoptions = new HighlightOptions();
        hightoptions.addField("name1");//设置高亮显示的域
        hightoptions.setSimplePrefix("<em style=\"color:red\">");
        hightoptions.setSimplePostfix("</em>");
        query.setHighlightOptions(hightoptions);

        if (searchMap.get("productCateId") != null && !"".equals(searchMap.get("productCateId"))) {
            Criteria fiterCriteria = new Criteria("productCateId").is(searchMap.get("productCateId"));
            FilterQuery filterQuery = new SimpleFilterQuery(fiterCriteria);
            query.addFilterQuery(filterQuery);
        }

        if (searchMap.get("cId") != null && !"".equals(searchMap.get("cId"))) {
            Criteria fiterCriteria = new Criteria("cId").contains((String) searchMap.get("cId"));
            FilterQuery filterQuery = new SimpleFilterQuery(fiterCriteria);
            query.addFilterQuery(filterQuery);
        }

        /*if (StringUtils.isNotBlank((CharSequence) searchMap.get("price"))){
            //item_price:[10 TO 20]
            String[] split = searchMap.get("price").toString().split("-");
            SimpleFilterQuery filterQuery = new SimpleFilterQuery();
            Criteria itemPrice = new Criteria("item_price");
            //如果有* 语法是不支持的
            if(!split[1].equals("*")){
                itemPrice.between(split[0],split[1],true,true);
            }else {
                itemPrice.greaterThanEqual(split[0]);
            }
            filterQuery.addCriteria(itemPrice);
            query.addFilterQuery(filterQuery);
        }*/

        //8.分页查询
        Integer pageNo = (Integer) searchMap.get("pageNo");//提取页面

        if (pageNo == null) {
            pageNo = 1;
        }
        Integer pageSize = (Integer) searchMap.get("pageSize");//每页记录数
        if (pageSize == null) {
            pageSize = 20;
        }
        query.setOffset((pageNo - 1) * pageSize);//从第几条记录查询
        query.setRows(pageSize);

        //9.排序
        String sortValue = (String) searchMap.get("sort");
        String sortField = (String) searchMap.get("sortField");//排序字段
        if (StringUtils.isNotBlank(sortField)) {
            if (sortValue.equals("ASC")) {
                Sort sort = new Sort(Sort.Direction.ASC, sortField);
                query.addSort(sort);
            }
            if (sortValue.equals("DESC")) {
                Sort sort = new Sort(Sort.Direction.DESC, sortField);
                query.addSort(sort);
            }
        }

        //10.执行查询 获取高亮数据
        HighlightPage<SolrProduct> highlightPage = solrTemplate.queryForHighlightPage("lhc_core", query, SolrProduct.class);

        List<HighlightEntry<SolrProduct>> highlighted = highlightPage.getHighlighted();
        for (HighlightEntry<SolrProduct> SolrProductHighlightEntry : highlighted) {
            SolrProduct entity = SolrProductHighlightEntry.getEntity();//实体对象 现在是没有高亮的数据的

            List<HighlightEntry.Highlight> highlights = SolrProductHighlightEntry.getHighlights();
            //如有高亮，就取高亮
            if (highlights != null && highlights.size() > 0 && highlights.get(0) != null && highlights.get(0).getSnipplets() != null && highlights.get(0).getSnipplets().size() > 0) {
                entity.setName1(highlights.get(0).getSnipplets().get(0));
            }
        }
        List<SolrProduct> SolrProducts = highlightPage.getContent();//获取高亮的文档的集合
        //11.执行查询
        System.out.println("结果" + SolrProducts.size());
        //12.获取结果集  返回
        resultMap.put("rows", SolrProducts);
        resultMap.put("totalPages", highlightPage.getTotalPages());//返回总页数
        resultMap.put("total", highlightPage.getTotalElements());//返回总记录数
        return resultMap;
    }

    public int addIndex(SolrProduct item) {
        UpdateResponse updateResponse = solrTemplate.saveBean("lhc_core", item);
        solrTemplate.commit("lhc_core");
        return updateResponse.getStatus();
    }

    public int deleteAll() {
        SimpleQuery query = new SimpleQuery("*:*");
        UpdateResponse updateResponse = solrTemplate.delete("lhc_core", query);
        solrTemplate.commit("lhc_core");
        return updateResponse.getStatus();
    }

    public int deleteById(String id) {
        UpdateResponse updateResponse = solrTemplate.deleteById("lhc_core", id);
        solrTemplate.commit("lhc_core");
        return updateResponse.getStatus();
    }

    public int createIndex() {
        UpdateResponse updateResponse = solrTemplate.saveBeans("lhc_core", init());
        solrTemplate.commit("lhc_core");
        return updateResponse.getStatus();
    }

    public JSONObject suggest(String search) {
        JSONObject result = new JSONObject();
        List<String> wordList = new ArrayList<String>();
        SolrQuery query = new SolrQuery();
        query.set("q", "search:" + search);//查询的词

        query.set("qt", "/suggest");//请求到suggest中

        query.set("spellcheck.count", "100");//返回数量

        QueryResponse queryResponse = null;
        try {
            queryResponse = client.query("lhc_core", query);
            //获取拼写检查的结果集
            SpellCheckResponse re = queryResponse.getSpellCheckResponse();

            if (re != null) {
                for (SpellCheckResponse.Suggestion s : re.getSuggestions()) {
                    List<String> list = s.getAlternatives();//获取所有 的检索词
                    for (String spellWord : list) {
                        wordList.add(spellWord);
                    }
                }
            }
            result.put("numFound", wordList.size());
            result.put("hotwords", wordList);
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    public int buildSuggestConf() {
        SolrQuery query = new SolrQuery();
        query.set("qt", "/suggest");
        query.set("spellcheck.build", true);
        QueryResponse response = null;

        try {
            response = client.query("lhc_core", query);
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response.getStatus();
    }

    public int writeSuggestConf(List<SuggestConf> confs, boolean append, String updateBy) {
        try {
            String suggestPath = PropertiesUtils.getInstance().getProperty("/domain.properties", "solr.sugeest.conf");

            File file = new File(suggestPath);

            List<String> lines = new ArrayList<String>();

            for (SuggestConf conf : confs) {
                lines.add(conf.getName() + "\t" + conf.getWeight());
            }

            write( append, updateBy, file, lines);

            //使配置生效
            buildSuggestConf();

        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
        return 0;

    }

    public int writeSuggestConfFile(File tempFile, CommonsMultipartFile requestFile, boolean append, String updateBy) {

        try {
            String suggestPath = PropertiesUtils.getInstance().getProperty("/domain.properties", "solr.sugeest.conf");

            File file = new File(suggestPath);

            requestFile.transferTo(tempFile);

            //读取上传的配置信息
            List<String> readLines = FileUtils.readLines(tempFile, "UTF-8");

            write( append, updateBy, file, readLines);

            //使配置生效
            buildSuggestConf();

            //删除临时文件
            FileUtils.deleteQuietly(tempFile);
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        }
        return 0;
    }

    private void write(boolean append,String updateBy,File file,List<String> readLines) throws IOException {
        if (append) {
            //如果是追加 增加注释行
            com.zmj.solr.util.FileUtils.writeRemarkLine(file,append,updateBy);

        } else {
            //如果是全部更新
//                FileUtils.copyDirectory(tempFile, file);
            readLines.add(0, com.zmj.solr.util.FileUtils.remarkLine(updateBy));
        }
        FileUtils.write(file, "\n", "UTF-8",append);
        FileUtils.writeLines(file, "UTF-8", readLines,append);
    }


    private List<SolrProduct> init() {
        List<SolrProduct> list = new ArrayList<SolrProduct>();
       /* list.add(new SolrProduct("1","联想手机 x522黑色","联想","大屏,4G", 1899,110,"1/11") );
        list.add(new SolrProduct("2","平板p92 大屏尺寸","小米","平板", 1398,120,"2/12") );
        list.add(new SolrProduct("3","iphone5 256G","苹果Apple","苹果", 6899,110,"1/11") );
        list.add(new SolrProduct("4","联想笔记本1T15寸屏幕","联想",",笔记本,15寸", 7688,110,"1/11") );
        list.add(new SolrProduct("5","小米时尚机","小米","游戏,4G,手机", 7688,110,"1/11") );
        list.add(new SolrProduct("6","终极时尚游戏笔记本","华为","时尚,游戏,笔记本", 5699,120,"2/12") );
        list.add(new SolrProduct("10","小米米家笔记本","小米","笔记本", 3998,120,"2/12") );
        list.add(new SolrProduct("7","苹果apple智能watch","苹果","智能,watch", 6878,120,"2/12") );
        list.add(new SolrProduct("8","华为watch","华为","华为,智能,watch", 1298,120,"2/12") );
        list.add(new SolrProduct("9","华为双4G大屏手机","华为","华为,手机", 3899,110,"1/11") );
        list.add(new SolrProduct("11","华为笔记本8G 512内存","华为","华为,笔记本", 8899,120,"2/12") );
        list.add(new SolrProduct("12","华为路由器","华为","华为,路由器", 698,120,"2/12") );
       */
        list.add(new SolrProduct("1", "联想手机 x522黑色", "联想", "联想手机", 1899, 110, "1/11"));
        list.add(new SolrProduct("2", "平板p92 大屏尺寸", "小米", "小米平板", 1398, 120, "2/12"));
        list.add(new SolrProduct("3", "iphone5 256G", "苹果Apple", "苹果Apple", 6899, 110, "1/11"));
        list.add(new SolrProduct("4", "联想笔记本1T15寸屏幕", "联想", "联想笔记本", 7688, 110, "1/11"));
        list.add(new SolrProduct("5", "小米时尚机", "小米", "小米手机", 7688, 110, "1/11"));
        list.add(new SolrProduct("6", "终极时尚游戏笔记本", "华为", "华为笔记本", 5699, 120, "2/12"));
        list.add(new SolrProduct("10", "小米米家笔记本", "小米", "小米笔记本", 3998, 120, "2/12"));
        list.add(new SolrProduct("7", "苹果apple智能watch", "苹果", "苹果applewatch", 6878, 120, "2/12"));
        list.add(new SolrProduct("8", "华为watch", "华为", "华为watch", 1298, 120, "2/12"));
        list.add(new SolrProduct("9", "华为双4G大屏手机", "华为", "华为手机", 3899, 110, "1/11"));
        list.add(new SolrProduct("11", "华为笔记本8G 512内存", "华为", "华为笔记本", 8899, 120, "2/12"));
        list.add(new SolrProduct("12", "华为路由器", "华为", "华为路由器", 698, 120, "2/12"));

        return list;
    }
}
